package com.xcity.game.pet;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xcity.db.entity.Player;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.event.GameEvents;
import com.xcity.game.item.ItemEffect;
import com.xcity.game.item.ItemTemplate;
import com.xcity.game.pet.Pet.State;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.push.msg.BuyTipPush;
import com.xcity.pomelo.request.CurrentWorkingPetInfoRequest;
import com.xcity.pomelo.request.PetChangeStateRequest;
import com.xcity.pomelo.request.PetFeedRequest;
import com.xcity.pomelo.request.PetInfoRequest;
import com.xcity.pomelo.request.PetLevelUpRequest;
import com.xcity.pomelo.request.PetListRequest;
import com.xcity.pomelo.request.PetPlayRequest;
import com.xcity.pomelo.request.PetWashRequest;
import com.xcity.pomelo.response.EmptyPetResponse;
import com.xcity.pomelo.response.HintResponse;
import com.xcity.pomelo.response.PetInfoResponse;
import com.xcity.pomelo.response.PetListResponse;
import com.xcity.pomelo.response.PetStateResponse;
import com.xcity.pomelo.response.Response;

import gnu.trove.map.TLongObjectMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.template.TemplateService;
import naga.x.game.time.TimeUpdater;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.Service;
import naga.x.service.ServiceException;
import naga.x.util.TimeUtils;

/**
 * 宠物系统
 * @author yang.li
 *
 */
@Deprecated
@OPHandler
public class PetService implements Service, EventListener {

	protected List<ItemTemplate> foods;
	protected TLongObjectMap<List<PetPlayAddSpiritTask>> pendingPlayPetTasks = new TLongObjectHashMap<List<PetPlayAddSpiritTask>>();
	
	protected static final int BEST_FOOD = 10022;
	protected static final Logger LOG = LoggerFactory.getLogger(PetService.class);
	
	@Override
	public void startup() throws ServiceException {
		foods = new ArrayList<ItemTemplate>();
		List<ItemTemplate> items = App.getApp().getServiceManager().get(TemplateService.class).getTemplatesList(ItemTemplate.class);
		for (int i = 0, size = items.size(); i < size; i++) {
			ItemTemplate item = items.get(i);
			if (item.getEffect() == ItemEffect.ADD_PET_SPIRIT) {
				foods.add(item);
			}
		}
		App.getApp().getEventManager().register(this);
	}

	@Override
	public void shutdown() throws ServiceException {
	}

	@Override
	public String getId() {
		return getClass().getName();
	}
	
	public List<ItemTemplate> getFoods() {
		return foods;
	}
	
	@PomeloOP(PomeloRoute.PET_LIST)
	protected void requestPetList(Session session, PetListRequest req) {
		Player player = session.getClient();
		session.send(new PetListResponse(req.getSerial(), player.getPets().getPets()));
	}
	
	@PomeloOP(PomeloRoute.PET_INFO)
	protected void requestPetInfo(Session session, PetInfoRequest req) {
		Player player = session.getClient();
		Pet pet = player.getPets().getPet(req.getId());
		if (pet == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_NOT_EXIST));
			return;
		}
		session.send(new PetInfoResponse(req.getSerial(), pet));
	}
	
	@PomeloOP(PomeloRoute.PET_CHANGE_STATE)
	protected void requestChangeState(Session session, PetChangeStateRequest req) {
		State state = State.codeOf(req.getState());
		if (state == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
			return;
		}
		Player player = session.getClient();
		Pet pet = player.getPets().getPet(req.getId());
		if (pet == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_NOT_EXIST));
			return;
		}
		if (pet.getState() == state) {
			session.send(new PetStateResponse(req.getSerial(), pet));
			return;
		}
		if (state == State.WORK) {
			player.getPets().setWorkingPet(pet);
		} else {
			player.getPets().setWorkingPet(null);
		}
		session.send(new PetStateResponse(req.getSerial(), pet));
	}
	
	@PomeloOP(PomeloRoute.PET_FEED)
	protected void requestFeed(Session session, PetFeedRequest req) {
		Player player = session.getClient();
		Pet pet = player.getPets().getPet(req.getId());
		if (pet == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_NOT_EXIST));
			return;
		}
		if (pet.getSpirit() >= pet.getTemplate().getSpirit()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_FEED_WHEN_SPIRIT_FULL));
			return;
		}
		for (ItemTemplate food : foods) {
			if (player.getBag().removeItem(food.getId(), 1, Cause.PET_FEED)) {
				int val = food.getParameter(0);
				pet.addSpirit(val, Cause.PET_FEED);
//				session.send(new HintResponse(req.getSerial(),
//						MessageFormat.format(MessageConst.PET_FEED_SUCC,
//												pet.getTemplate().getName(),
//												food.getName(),
//												pet.getSpirit())));
				App.getApp().getEventManager().addEvent(GameEvents.EVENT_FEED_PET, player, pet);
				session.send(new PetSimpleInfo(req.getSerial(), pet));
				return;
			}
		}
		session.send(new BuyTipPush(player, BEST_FOOD));
		session.send(new Response(req.getSerial()));
//		session.send(new HintResponse(req.getSerial(), MessageConst.PET_FOOD_NOT_ENOUGH));
	}
	
//	// 洗澡确认框
//	static class PetWashOperation extends AbstractConfirmOperation {
//		private Pet pet;
//		private int gold;
//		
//		public PetWashOperation(Player ref, Pet pet, int gold, String msg) {
//			super(ref, msg);
//			this.pet = pet;
//			this.gold = gold;
//		}
//
//		@Override
//		public void ok(Player player) {
//			if (!player.costGold(gold, Cause.PET_WASH)) {
//				player.send(new TipPush(MessageConst.STONE_NOT_ENOUTH));
//				return;
//			}
//			pet.setLastWashTime(TimeUpdater.getInstance().now());
//			pet.addSpirit((int) (pet.getTemplate().getSpirit() * 0.2), player, Cause.PET_WASH);
//			player.send(new CustomSync(SyncPush.SYNC_PET, new PetSimpleInfo(pet)));
//			player.send(new TipPush(MessageFormat.format(MessageConst.PET_WASH_SUCC, pet.getTemplate().getName(), pet.getSpirit())));
//		}
//	}
	@PomeloOP(PomeloRoute.PET_WASH)
	protected void requestWash(Session session, PetWashRequest req) {
		Player player = session.getClient();
		Pet pet = player.getPets().getPet(req.getId());
		if (pet == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_NOT_EXIST));
			return;
		}
		if (pet.getSpirit() >= pet.getTemplate().getSpirit()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_WASH_WHEN_SPIRIT_FULL));
			return;
		}
		int leftCD = pet.getWashCD();
		if (leftCD > 0) {
			String tip;
			if (leftCD >= TimeUnit.HOURS.toMillis(1)) {
				tip = MessageFormat.format(MessageConst.PET_WASH_IN_CD, TimeUnit.MILLISECONDS.toHours(leftCD) + "小时后");
			} else if (leftCD >= TimeUnit.MINUTES.toMillis(1)) {
				tip = MessageFormat.format(MessageConst.PET_WASH_IN_CD, TimeUnit.MILLISECONDS.toMinutes(leftCD) + "分钟后");
			} else if (leftCD >= TimeUnit.SECONDS.toMillis(1)) {
				tip = MessageFormat.format(MessageConst.PET_WASH_IN_CD, TimeUnit.MILLISECONDS.toSeconds(leftCD) + "秒后");
			} else {
				tip = MessageFormat.format(MessageConst.PET_WASH_IN_CD, "稍等一会儿");
			}
			session.send(new HintResponse(req.getSerial(), tip));
			return;
		}
//		new PetWashOperation(player, pet, pet.getTemplate().getWashCost(), MessageFormat.format(MessageConst.PET_WASH_TIP, pet.getTemplate().getWashCost())).send();
		if (!player.costGold(pet.getTemplate().getWashCost(), Cause.PET_WASH)) {
			player.send(new HintResponse(req.getSerial(), MessageConst.STONE_NOT_ENOUTH));
			return;
		}
		pet.setLastWashDay(TimeUpdater.getInstance().today());
		pet.addSpirit((int) (pet.getTemplate().getSpirit() * 0.2), Cause.PET_WASH);
//		player.send(new CustomSync(SyncPush.SYNC_PET, new PetSimpleInfo(pet)));
//		player.send(new TipPush(MessageFormat.format(MessageConst.PET_WASH_SUCC, pet.getTemplate().getName(), pet.getSpirit())));
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_WASH_PET, player, pet);
		session.send(new PetSimpleInfo(req.getSerial(), pet));
	}
	
	class PetPlayAddSpiritTask implements Runnable {
		private Player player;
		private Pet pet;
		private ScheduledFuture<?> future;
		public PetPlayAddSpiritTask(Player player, Pet pet) {
			this.player = player;
			this.pet = pet;
			this.future = App.getApp().getSchedule().schedule(this, 30, TimeUnit.SECONDS);
		}
		@Override
		public void run() {
			pet.addSpirit((int) (pet.getTemplate().getSpirit() * 0.08), Cause.PET_PLAY);
			List<PetPlayAddSpiritTask> list = pendingPlayPetTasks.get(player.getId());
			if (list != null) {
				list.remove(this);
			}
		}
	}
	
	@PomeloOP(PomeloRoute.PET_PLAY)
	protected void requestPlay(Session session, PetPlayRequest req) {
		Player player = session.getClient();
		Pet pet = player.getPets().getPet(req.getId());
		if (pet == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_NOT_EXIST));
			return;
		}
		if (pet.getSpirit() >= pet.getTemplate().getSpirit()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_PLAY_WHEN_SPIRIT_FULL));
			return;
		}
		int lastPlayDay = TimeUtils.ofDay(pet.getLastPlayTime());
		if (lastPlayDay != TimeUpdater.getInstance().today()) {
			pet.setTodayPlayTimes(0); // 重置次数
		} else if (pet.getTodayPlayTimes() >= Pet.PLAY_MAX_TIMES_PER_DAY) { // 超过今日总次数
			session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.PET_PLAY_IN_CD, "明天")));
			return;
		}
		int leftCD = pet.getPlayCD();
		if (leftCD > 0) {
			if (leftCD >= TimeUnit.MINUTES.toMillis(1)) {
				session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.PET_PLAY_IN_CD, TimeUnit.MILLISECONDS.toMinutes(leftCD) + "分钟后")));
			} else {
				session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.PET_PLAY_IN_CD, "稍等一会儿")));
			}
			return;
		}
		pet.setLastPlayTime(TimeUpdater.getInstance().now());
		pet.setTodayPlayTimes(pet.getTodayPlayTimes() + 1);
		List<PetPlayAddSpiritTask> tasks = pendingPlayPetTasks.get(player.getId());
		if (tasks == null) {
			tasks = new ArrayList<PetPlayAddSpiritTask>(3);
			pendingPlayPetTasks.put(player.getId(), tasks);
		}
		tasks.add(new PetPlayAddSpiritTask(player, pet));
//		session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.PET_PLAY_SUCC, pet.getTemplate().getName())));
//		session.send(new CustomSync(SyncPush.SYNC_PET, new PetSimpleInfo(pet)));
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_PLAY_PET, player, pet);
		session.send(new PetSimpleInfo(req.getSerial(), pet));
	}
	
	@PomeloOP(PomeloRoute.WORKING_PET_INFO)
	protected void requestCurrentWorkingPetInfo(Session session, CurrentWorkingPetInfoRequest req) {
		Player player = session.getClient();
		Pet pet = player.getPets().getWorkingPet();
		if (pet != null) {
			session.send(new PetInfoResponse(req.getSerial(), pet));
		} else {
			session.send(new EmptyPetResponse(req.getSerial()));
		}
	}
	
	@PomeloOP(PomeloRoute.PET_LEVEL_UP)
	protected void requestLevelUp(Session session, PetLevelUpRequest req) {
		Player player = session.getClient();
		Pet pet = player.getPets().getPet(req.getId());
		if (pet == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PET_NOT_EXIST));
			return;
		}
		int exp = pet.getExp();
		if (exp <= 0) {
			session.send(new HintResponse(req.getSerial(), MessageConst.CAN_NOT_LEVEL_UP));
			return;
		}
		pet.addLevel(exp, Cause.MANUAL);
		session.send(new PetSimpleInfo(req.getSerial(), pet));
	}

	@Override
	public int[] getEventTypes() {
		return new int[] { GameEvents.EVENT_PLAYER_LOGOUT };
	}

	@Override
	public void handleEvent(Event event) {
//		switch (event.getType()) {
//			case GameEvents.EVENT_PLAYER_LOGOUT:
				playerLogout(event.getParameter());
//				break;
//		}
	}
	
	private void playerLogout(Player player) {
		List<PetPlayAddSpiritTask> pendingTasks = pendingPlayPetTasks.remove(player.getId());
		if (pendingTasks != null) {
			for (int i = pendingTasks.size() - 1; i >= 0; i--) {
				PetPlayAddSpiritTask task = pendingTasks.get(i);
				if (!task.future.isCancelled()
						&& !task.future.isDone()
						&& task.future.cancel(false)) {
					task.run();
				}
			}
		}
	}

}
